package org.jeecg.app.modules.security.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.edu.umsUser.entity.UmsUser;
import org.jeecg.modules.edu.umsUser.parm.LoginParam;
import org.jeecg.modules.edu.umsUser.parm.UserEditParam;
import org.jeecg.modules.edu.umsUser.service.IUmsUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author scott
 * @since 2018-12-17
 */
@RestController
@RequestMapping("/auth")
@Slf4j
public class LoginController {

    @Autowired
    private IUmsUserService umsUserService;

    @Autowired
    private RedisUtil redisUtil;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result<JSONObject> login(@RequestBody LoginParam loginParam) {
        Result<JSONObject> result = new Result<JSONObject>();
        String username = loginParam.getUsername();
        String password = loginParam.getPassword();

        //1. 校验用户是否有效
        //update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug，if条件永远为false
        LambdaQueryWrapper<UmsUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UmsUser::getUsername, username);
        UmsUser umsUser = umsUserService.getOne(queryWrapper);
        //update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug，if条件永远为false
        result = umsUserService.checkUserIsEffective(umsUser);
        if (!result.isSuccess()) {
            return result;
        }

        //2. 校验用户名或密码是否正确

        String userpassword = PasswordUtil.encrypt(username, password, umsUser.getSalt());
        String syspassword = umsUser.getPassword();
        if (!syspassword.equals(userpassword)) {
            result.error500("用户名或密码错误");
            return result;
        }
        //用户登录信息
        userInfo(umsUser, result);

        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(umsUser, loginUser);

        return result;
    }

    /**
     * 获取当前登陆人信息
     */
    @GetMapping("/userinfo")
    public Result<?> info() {
        UmsUser umsUser = (UmsUser) StpUtil.getSession().get("umsUser");
        return Result.OK("获取成功", umsUser);
    }

    @PostMapping("/user/edit")
    public Result<?> edit(@Validated @RequestBody UserEditParam param) {
        UmsUser pmsMember = (UmsUser) StpUtil.getSession().get("umsUser");
        pmsMember.setAvatar(param.getAvatar());
        pmsMember.setNickname(param.getNickname());

        umsUserService.updateById(pmsMember);

        return Result.OK("修改成功");
    }

    /**
     * 退出登录
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/logout")
    public Result<Object> logout(HttpServletRequest request, HttpServletResponse response) {
        //用户退出逻辑
        String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
        if (oConvertUtils.isEmpty(token)) {
            return Result.error("退出登录失败！");
        }
        String username = JwtUtil.getUsername(token);

        LambdaQueryWrapper<UmsUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UmsUser::getUsername, username);
        UmsUser umsUser = umsUserService.getOne(queryWrapper);
        if (umsUser != null) {
            log.info(" 用户名:  " + umsUser.getNickname() + ",退出成功！ ");
            //清空用户登录Token缓存
            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
            //清空用户登录Shiro权限缓存
            redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + umsUser.getId());
            //调用sa-token的logout
            StpUtil.logout();
            return Result.ok("退出登录成功！");
        } else {
            return Result.error("Token无效!");
        }
    }


    /**
     * 用户信息
     *
     * @param umsUser
     * @param result
     * @return
     */
    private Result<JSONObject> userInfo(UmsUser umsUser, Result<JSONObject> result) {
        JSONObject obj = new JSONObject();
        StpUtil.login(umsUser.getId());
        StpUtil.getSession().set("umsUser", umsUser);
        SaTokenInfo saTokenInfo = StpUtil.getTokenInfo();

        obj.put("token", saTokenInfo);
        obj.put("userInfo", umsUser);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }

}